
#ifdef INT
#  define TYP INTEGER
#else
#ifdef FLOAT
#  define TYP REAL
#else
 #error "Need to give MACRO definition for element type : -DTYPE_INT or -DTYPE_FLOAT"
#endif
#endif


PROGRAM PROG_PRINC
!
!compilation : gfortran prog_princ.f90 -fbounds-check
!
IMPLICIT NONE
!DECLARATION DES PARAMETRES


	! LA TAILLE DES MATRICES EST ENTREE EN LIGNE DE COMMANDE LORS DE L' EXECUTION
	INTEGER :: p = 0

	INTEGER :: DIM1
	INTEGER :: F_COMPTEUR
	INTEGER :: NMAX
	INTEGER :: I,J
	TYP :: S

	REAL :: INTERMEDIAIRE
	INTEGER :: VALEURMAX,VALEURMIN

	INTEGER :: order
	CHARACTER(len=32) :: arg

 	!********************POUR LE STOCKAGE EI
 	TYP, DIMENSION (:,:), ALLOCATABLE :: AA
 	INTEGER, DIMENSION (:,:), ALLOCATABLE :: BB

 	TYP,DIMENSION(:),ALLOCATABLE :: U
 	INTEGER :: IERR

 	TYP,DIMENSION(:),ALLOCATABLE :: V
 
	!**lecture des arguments en ligne de commande
	DO P=0,2
		CALL get_command_argument(p, arg)
		IF (LEN_TRIM(arg) == 0) exit 
		!WRITE (*,*) TRIM(arg)
		IF (p == 1) THEN
			read ( arg , '(i10)') DIM1
		ELSEIF (p == 2) THEN
			read ( arg , '(i10)') F_COMPTEUR
		ENDIF
	END DO

 	NMAX=DIM1-1

	!********************POUR LE STOCKAGE EI
	ALLOCATE (AA(DIM1,NMAX),STAT=IERR)
	ALLOCATE (BB(DIM1,NMAX),STAT=IERR)
	ALLOCATE (U(DIM1))
	ALLOCATE (V(DIM1))



	IF(IERR.NE.0) STOP 'ERREUR pour l allocation des matrices/vecteurs!'

	VALEURMAX=100000
	VALEURMIN=-100000
	! PRENONS A DIAGONALE (COEFF ALEATOIRES)
	DO I=1,DIM1
		V(I)=0
		CALL RANDOM_NUMBER(INTERMEDIAIRE)
		AA(I,1)=INTERMEDIAIRE*(VALEURMAX-VALEURMIN)+VALEURMIN		
		BB(I,1)=I
		U(I)=I
		DO J=2,NMAX
			AA(I,J)=0
			BB(I,J)=I
		END DO
	END DO

!!!AFFICHONS LA MATRICE BB        
!	 DO I=1,DIM1
!	   WRITE(*,*) (BB(I,J),J=1,NMAX)
!	 END DO


	!APPEL DES SUBROUTINES  
	CALL SPMV_EI(AA,BB,U,V,DIM1,NMAX,F_COMPTEUR)

	! ON DESALLOUE TOUT CE QU'ON A ALLOUE
	DEALLOCATE(V)
	DEALLOCATE(U)
	DEALLOCATE(AA)
	DEALLOCATE(BB)

	!END DO

	!-------------------------------------------------------------------------------------------------------------------------------
	!-------------------------------------------------------------------------------------------------------------------------------
	!-------------------------------------------------------------------------------------------------------------------------------
	!-------------------------------------------------ESPACE SUBROUTINES------------------------------------------------------------
	!-------------------------------------------------------------------------------------------------------------------------------
	!-------------------------------------------------------------------------------------------------------------------------------
	!-------------------------------------------------------------------------------------------------------------------------------
	CONTAINS


	!SUBROUTINES MATRICE CREUSE EI

	!-----------------------------------------------------------------------------
	! Fonction : SPMV_EI
	! Description :- calcul le produit matrice_creuse/vecteur et enregistre le temps d'execution et les parametre de la matrice dans un fichier
	!                pour un stockage creux du type Ellpack_Itpack, on a 2 tableaux de tailles dim*Nmax, dont un stocke les valeurs des coefficients non nuls par ligne
	!                et un tableau qui contient les numéros de colonne des elements non nuls
	!              - T **AA stocke les valeurs des coefficients non nuls par ligne
	!              - T *u, le vecteur multiplie
	!              - T *v, le vecteur resultat
	! 			   - int dim la dimension de la matrice
	!              - Nmax = max(Nmax[i]) avec Nmax(i], le nombre maximum de valeurs non nuls sur la ligne i
	! Retour: aucun
	!-----------------------------------------------------------------------------  
	SUBROUTINE SPMV_EI(AA,BB,U,V,DIM1,NMAX,F_COMPTEUR)
	!DECLARATIONS PARAMETRES
	REAL *8:: T1,T2,TEMPS_MOY=0.0
	INTEGER :: I,K,COMPTEUR=0
	CHARACTER*80 :: FORME="stockage Ellpack Itpack"
	INTEGER, INTENT (IN) :: DIM1,NMAX,F_COMPTEUR
	TYP,DIMENSION(:), INTENT (IN) :: U
	TYP, DIMENSION (:,:), INTENT (IN) :: AA
	INTEGER,DIMENSION (:,:), INTENT (IN) :: BB
	TYP,DIMENSION(:), INTENT (OUT):: V


	!CALCUL PRODUIT
	DO COMPTEUR=1,F_COMPTEUR

		!TOP CHRONO
		CALL CPU_TIME(T1)
		DO I=1,DIM1
			DO K=1,NMAX
			V(I)=V(I)+AA(I,K)*U(BB(I,K))
			!WRITE (6,*) 'on affiche AA(',I,K,')',AA(I,K)
			!WRITE (6,*) 'on affiche BB(',I,K,')',BB(I,K)
			END DO
		END DO
		!STOP CHRONO 
		CALL CPU_TIME(T2)

		TEMPS_MOY=T2 -T1+TEMPS_MOY
	END DO
	TEMPS_MOY=TEMPS_MOY/F_COMPTEUR
	WRITE(*,*) TEMPS_MOY


	END SUBROUTINE SPMV_EI
	!-------------------------------------------------------------------------------------------------------------------------------
	!-------------------------------------------------END SUBROUTINES------------------------------------------------------------
	!-------------------------------------------------------------------------------------------------------------------------------
	!-------------------------------------------------------------------------------------------------------------------------------

END PROGRAM PROG_PRINC

!------------------------------------------------------------------------------
!MESSAGE D'ERREUR RETOURNER DANS LE TERMINAL
!a.out: malloc.c:3096: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.
!Abandon
!--------------------------------------------------------------------------------------

